package com.zzyy.study.juc;

import jakarta.annotation.Resource;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.RestController;

import java.sql.Connection;
import java.util.concurrent.*;

/**
 * @auther zzyy
 * @create 2025-01-20 14:36
 */
@Component
public class CompletableFutureDemo
{
    public void getCustomerInfo()
    {
        try { TimeUnit.MILLISECONDS.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); }
    }
    public void getScore()
    {
        try { TimeUnit.MILLISECONDS.sleep(200); } catch (InterruptedException e) { e.printStackTrace(); }
    }
    public void getOrderInfo()
    {
        try { TimeUnit.MILLISECONDS.sleep(300); } catch (InterruptedException e) { e.printStackTrace(); }
    }

    public void findOld()
    {
        long startTime = System.currentTimeMillis();

        this.getCustomerInfo();
        this.getScore();
        this.getOrderInfo();

        long endTime = System.currentTimeMillis();
        System.out.println("----costTime: "+(endTime - startTime) +" 毫秒");
    }

    public void findNew() throws ExecutionException, InterruptedException
    {
        Customer customer = new Customer();

        long startTime = System.currentTimeMillis();

        CompletableFuture<String> future1 = CompletableFuture.supplyAsync(() -> {
            System.out.println(Thread.currentThread().getName()+"\t"+"111");
            this.getCustomerInfo();
            customer.setId(123);
            return "OK";
        });
        CompletableFuture<String> future2 = CompletableFuture.supplyAsync(() -> {
            System.out.println(Thread.currentThread().getName()+"\t"+"222");
            this.getScore();
            return "OK";
        });
        CompletableFuture<String> future3 = CompletableFuture.supplyAsync(() -> {
            System.out.println(Thread.currentThread().getName()+"\t"+"333");
            this.getOrderInfo();
            return "OK";
        });

        CompletableFuture<Void> alled = CompletableFuture.allOf(future1, future2, future3);
        alled.get();

        long endTime = System.currentTimeMillis();
        System.out.println("----costTime: "+(endTime - startTime) +" 毫秒");
    }

    public void findNew2() throws ExecutionException, InterruptedException
    {
        Customer customer = new Customer();

        ExecutorService threadPool1 = Executors.newFixedThreadPool(3);//固定数线程池
        ExecutorService threadPool2 = Executors.newSingleThreadExecutor();//一池1线程
        Executors.newCachedThreadPool();



        ThreadPoolExecutor threadPool = new ThreadPoolExecutor(
                Runtime.getRuntime().availableProcessors() + 1,
                Runtime.getRuntime().availableProcessors() * 2,
                1L,TimeUnit.SECONDS,
                new LinkedBlockingQueue<>(10));

        long startTime = System.currentTimeMillis();


        CompletableFuture<String> future1 = CompletableFuture.supplyAsync(() -> {
            System.out.println(Thread.currentThread().getName()+"\t"+"111");
            this.getCustomerInfo();
            customer.setId(777);
            return "OK";
        },threadPool);

        CompletableFuture<String> future2 = CompletableFuture.supplyAsync(() -> {
            System.out.println(Thread.currentThread().getName()+"\t"+"222");
            this.getScore();
            return "OK";
        },threadPool);

        CompletableFuture<String> future3 = CompletableFuture.supplyAsync(() -> {
            System.out.println(Thread.currentThread().getName()+"\t"+"333");
            this.getOrderInfo();
            return "OK";
        },threadPool);

        CompletableFuture<Void> alled = CompletableFuture.allOf(future1, future2, future3);
        alled.get();

        long endTime = System.currentTimeMillis();
        System.out.println("----costTime: "+(endTime - startTime) +" 毫秒");

        threadPool.shutdown();
    }


    public static void main(String[] args) throws ExecutionException, InterruptedException
    {
        CompletableFutureDemo demo = new CompletableFutureDemo();

        //demo.findOld();
        //demo.findNew();
        //demo.findNew2();
    }
}


@AllArgsConstructor
@NoArgsConstructor
@Data
class Customer
{
    private int id;
    private String customerName;
    private String mark1;
    private String mark2;
}